package com.zhiwei.gateway.util;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.auth0.jwt.interfaces.JWTVerifier;
import lombok.extern.slf4j.Slf4j;

import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * function JWT工具类 <br/>
 *
 * Token校验顺序： 有效期校验--> Token用户信息校验
 * author zhiwei.yang
 * time 2020-2-26-18:03
 */
@Slf4j
public class JwtUtil {

    private JwtUtil(){}

    private static final String SECRET = "MDk4ZjZiY2Q0NjIxZDM3M2NhZGU0ZTgzMjYyN2I0ZjY";
    private static final String ISSUER = "zhiwei_yang";
    public static final String NAME = "name";
    public static final String EXPIRE = "exp";
    private static final Integer EXPIRE_TIME_SECONDS = 60 * 60;//有效期


    /**
     * 生成Token
     * @return
     */
    public static String createJwtToken(String username){
        Map<String, String> claimMap = new HashMap<>(1);
        claimMap.put(NAME, username);
        return createJwtToken(claimMap);
    }

    /**
     * 生成token
     * @param claims
     * @return
     */
    public static String createJwtToken(Map<String, String> claims){
        try {
            Algorithm algorithm = Algorithm.HMAC256(SECRET);
            JWTCreator.Builder builder = JWT.create()
                    .withIssuer(ISSUER)
                    .withExpiresAt(new Date(System.currentTimeMillis() + (EXPIRE_TIME_SECONDS * 1000L))); //10分钟过期
            claims.forEach(builder::withClaim);
            return builder.sign(algorithm);
        } catch (IllegalArgumentException e) {
            log.error("Jwt生成Token失败 claims ==> {}", claims, e);
            return "";
        }
    }

    /**
     * 校验jwt Token(内部包含有效期校验)，并返回数据
     */
    public static Map<String, Object> parseJwtToken(String jwtToken) {
        try {
            Algorithm algorithm = Algorithm.HMAC256(SECRET);
            JWTVerifier verifier = JWT.require(algorithm).withIssuer(ISSUER).build();
            DecodedJWT decodedJWT = verifier.verify(jwtToken);
            Map<String, Claim> claimMap = decodedJWT.getClaims();
            Map<String, Object> resultMap = new HashMap<>(claimMap.size());
            resultMap.put(EXPIRE, claimMap.get(EXPIRE).asInt());
            resultMap.put(NAME, claimMap.get(NAME).asString());
            log.info("Jwt Token解析，jwtToken:[{}], resultMap ==> {}", jwtToken, resultMap);
            return resultMap;
        } catch (Exception e) {
           log.error("Token格式解析失败 jwtToken ==> {}", jwtToken, e);
           return Collections.emptyMap();
        }
    }
}
